package com.example.selfservicestation.fragment

import android.os.Bundle
import android.text.Editable
import android.util.Log
import android.view.View
import androidx.core.os.bundleOf
import androidx.core.widget.doAfterTextChanged
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.example.selfservicestation.R
import com.example.selfservicestation.base.BaseBindingFragment
import com.example.selfservicestation.constant.DEFAULT_LOCK_COUNT
import com.example.selfservicestation.constant.DEFAULT_LOGIN_PHONE
import com.example.selfservicestation.constant.EXTRA_LOCK_ON_NUM
import com.example.selfservicestation.constant.SP_LOCK_COUNT
import com.example.selfservicestation.constant.SP_LOGIN_PHONE
import com.example.selfservicestation.databinding.FragmentPhoneBinding
import com.example.selfservicestation.enums.LockStateEnum
import com.example.selfservicestation.extensions.safeNavigate
import com.example.selfservicestation.global.GlobalParams
import com.example.selfservicestation.mob.MBFrame
import com.example.selfservicestation.mob.MODBUS_MIN_SEND_INTERVAL
import com.example.selfservicestation.mob.ModBusController
import com.example.selfservicestation.singleton.SharedPreferenceUtil
import com.example.selfservicestation.util.Audio
import com.example.selfservicestation.util.Tip
import com.example.selfservicestation.util.getBitValueFrom8Bits
import com.example.selfservicestation.util.showToast
import com.example.selfservicestation.util.toHexString
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class PhoneFragment: BaseBindingFragment<FragmentPhoneBinding>(FragmentPhoneBinding::inflate) {

    private val loginPhone = SharedPreferenceUtil.getString(SP_LOGIN_PHONE, DEFAULT_LOGIN_PHONE)
    private val lockCount = SharedPreferenceUtil.getInt(SP_LOCK_COUNT, DEFAULT_LOCK_COUNT)
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initViews()

    }

    private fun initViews(){
        binding.etPhone.text = ""
        binding.layoutNumber.tvNumber0.setOnClickListener {
            binding.etPhone.append("0")
        }
        binding.layoutNumber.tvNumber1.setOnClickListener {
            binding.etPhone.append("1")
        }
        binding.layoutNumber.tvNumber2.setOnClickListener {
            binding.etPhone.append("2")
        }
        binding.layoutNumber.tvNumber3.setOnClickListener {
            binding.etPhone.append("3")
        }
        binding.layoutNumber.tvNumber4.setOnClickListener {
            binding.etPhone.append("4")
        }
        binding.layoutNumber.tvNumber5.setOnClickListener {
            binding.etPhone.append("5")
        }
        binding.layoutNumber.tvNumber6.setOnClickListener {
            binding.etPhone.append("6")
        }
        binding.layoutNumber.tvNumber7.setOnClickListener {
            binding.etPhone.append("7")
        }
        binding.layoutNumber.tvNumber8.setOnClickListener {
            binding.etPhone.append("8")
        }
        binding.layoutNumber.tvNumber9.setOnClickListener {
            binding.etPhone.append("9")
        }
        binding.layoutNumber.tvNumberClear.setOnClickListener {
            val input = binding.etPhone.text.toString()
            if (input.length < 11){
                Tip.audio(R.raw.phone_wrong)
                return@setOnClickListener
            }
            if (binding.etPhone.text.toString() == loginPhone) {
                GlobalParams.loginPhoneOrCard = input
                checkLockState()
            } else {
                Tip.audio(R.raw.phone_not_exist)
            }
        }
        binding.layoutNumber.tvDelete.setOnClickListener {
            binding.etPhone.text.toString().apply {
                if (this.isNotBlank()){
                    binding.etPhone.text = substring(0,this.length - 1)
                }
            }
        }

//        binding.etPhone.doAfterTextChanged { text: Editable? ->
//            text?.let {
//                if (it.toString() == loginPhone) {
////                    openLock(20)
//                    checkLockState()
//                    }
//                }
//            }

//        binding.layoutBack.setOnClickListener {
//            findNavController().navigateUp()
//        }
    }

    /**
     * 开锁，index从1开始
     */
    private fun openLock(index: Int){
        ModBusController.modBusManager?.sendTo(0, MBFrame(index - 1), false, MODBUS_MIN_SEND_INTERVAL) { resData ->
            Log.d("MainActivity", resData.toHexString(true))
            viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
                showToast("${index}号锁已打开")
                val bundle = bundleOf(EXTRA_LOCK_ON_NUM to index)
                findNavController().safeNavigate(R.id.phoneFragment_to_pocketSuccessFragment,bundle)
            }
        }
    }

    private fun checkLockState(){
        ModBusController.modBusManager?.sendTo(0, MBFrame(lockIndex = -1), false, MODBUS_MIN_SEND_INTERVAL) { resData ->
            Log.d("MainActivity", resData.toHexString(true))
            viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
                getLockDetailInfo(resData)
            }
        }
    }

    private fun getLockDetailInfo(byteArray: ByteArray){
        if (byteArray.size < 10) return
        val dataByteArray = byteArray.copyOfRange(5, byteArray.size - 1)
        Log.i("PhoneFragment",dataByteArray.toHexString())
        val bitList = arrayListOf<LockStateEnum>()
        outer@ for (item in dataByteArray){
            for (bitItem in 0..7){
                if(getBitValueFrom8Bits(item,bitItem) == 0){
                    bitList.add(LockStateEnum.OPEN)
                } else {
                    bitList.add(LockStateEnum.LOCK)
                }
                if (bitList.size == lockCount - 4) { //最多20个锁
                    break@outer
                }
            }
        }
        Log.i("PhoneFragment",bitList.toString())
        for ((index, item) in bitList.withIndex()){
            if (item == LockStateEnum.LOCK){
                openLock(index + 1)
                return
            }
        }
        showToast("所有的锁都已打开")
        Tip.audio(R.raw.all_phone_was_turn_on)
    }

}